
Imports std

Public Class runassvc
    Inherits ServiceBase

    Protected Friend Class argname
        Protected Friend Const appname As String = "appname"
        Protected Friend Const argument As String = "argument"
        Protected Friend Const username As String = "username"
        Protected Friend Const password As String = "password"
        Protected Friend Const domain As String = "domain"
        Protected Friend Const path As String = "path"
    End Class

    Protected Friend WithEvents proc As Process = Nothing
    Protected Friend appname As String = Nothing
    Protected Friend argument As String = Nothing
    Protected Friend username As String = Nothing
    Protected Friend password As String = Nothing
    Protected Friend domain As String = Nothing
    Protected Friend path As String = Nothing
    Protected Friend iargs() As String = Nothing

    Protected Friend Sub angel()
        On Error Resume Next

        Threading.Thread.Sleep(5000)

        If proc Is Nothing OrElse proc.HasExited Then
            Me.Stop()
        End If
    End Sub

    Protected Overrides Sub OnStart(ByVal _args() As String)
        ' Add code here to start your service. This method should set things
        ' in motion so your service can do its work.
#If DEBUG Then
        sleep(10000)
#End If

        Dim args As map(Of String, vector(Of String)) = Nothing
        argmgr.parse(iargs, args, True)

        If Not argmgr.getfirstvalue(args, argname.appname, appname) Then
            GoTo ext
        End If

        argmgr.getfirstvalue(args, argname.argument, argument)
        argmgr.getfirstvalue(args, argname.username, username)
        argmgr.getfirstvalue(args, argname.password, password)
        argmgr.getfirstvalue(args, argname.domain, domain)
        argmgr.getfirstvalue(args, argname.path, path)

        proc = New Process()
        proc.StartInfo.FileName = appname
        proc.StartInfo.Arguments = argument
        If isemptystring(path) Then
            proc.StartInfo.WorkingDirectory = parentpath(appname)
        Else
            proc.StartInfo.WorkingDirectory = path
        End If
        If Not isemptystring(username) Then
            proc.StartInfo.UserName = username
            proc.StartInfo.Password = New System.Security.SecureString()
            proc.StartInfo.Domain = domain
            Dim i As Int32
            For i = 0 To strlen(password) - 1
                proc.StartInfo.Password.AppendChar(password(i))
            Next
            proc.StartInfo.UseShellExecute = False
        End If
        proc.EnableRaisingEvents = True

        proc.Start()

        Dim t As Threading.Thread = Nothing
        t = New Threading.Thread(AddressOf angel)
        t.Start()

ext:

    End Sub

    Protected Overrides Sub OnStop()
        ' Add code here to perform any tear-down necessary to stop your service.
        On Error Resume Next

        If Not proc Is Nothing AndAlso Not proc.HasExited Then
            closeProcess(proc)
        End If
    End Sub

    Public Sub New(ByVal args() As String)

        ' This call is required by the Windows Form Designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        iargs = args
    End Sub

    Private Sub proc_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles proc.Exited
        Me.Stop()
    End Sub
End Class
